/*
 * Copyright (c) 2006-2021, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2022-08-28     chenbin       the first version
 */
#include <rtthread.h>
#include "ch32v30x.h"

#define TIM_ENCODER   TIM5

//volatile int  encoder_dir = 0;
//
//int encoder_dir_get(void)
//{
//    return encoder_dir;
//}
//
//void encoder_dir_set(int dir)
//{
//    encoder_dir = dir;
//    if(encoder_dir == MOTOR_DIR_DOWN)
//    {
//        TIM_CounterModeConfig(TIM_ENCODER, TIM_CounterMode_Up); //正方向
//    }else
//    if(encoder_dir == MOTOR_DIR_UP)
//    {
//        TIM_CounterModeConfig(TIM_ENCODER, TIM_CounterMode_Down); //负方向
//    }
//}

#define COUNTER_ZERO  100

volatile uint16_t    encoder_val = COUNTER_ZERO;
volatile int         encoder_level = 0;

int encoder_pos_get(void)
{
    int pos = 0;

    encoder_val = TIM_GetCounter(TIM_ENCODER); //CNT

    pos = (int)((encoder_level) * (int)65535) + encoder_val - COUNTER_ZERO;
    return pos;
}

void encoder_pos_set(int pos)
{
    encoder_val = COUNTER_ZERO + (pos%65535);

    TIM_SetCounter(TIM_ENCODER, encoder_val); //CNT

    encoder_level = pos/65535;
}

void TIM5_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
void TIM5_IRQHandler(void)
{
    GET_INT_SP();
    rt_interrupt_enter();
    if( TIM_GetITStatus( TIM_ENCODER, TIM_IT_Update ) != RESET )
    {
        TIM_ClearITPendingBit( TIM_ENCODER, TIM_IT_Update);
//        //计算标志位使能且上升，位置减
//        if(encoder_dir == MOTOR_DIR_UP)
//        {
//            encoder_level--;
//        }else
//        if(encoder_dir == MOTOR_DIR_DOWN)
//        {
//            encoder_level++;
//        }

        if( (TIM_ENCODER->CTLR1 & TIM_DIR) == TIM_CounterMode_Up)
        {
            encoder_level++;
        }else
        if( (TIM_ENCODER->CTLR1 & TIM_DIR) == TIM_CounterMode_Down)
        {
            encoder_level--;
        }
        rt_kprintf("tim5 update: %d \n\r",encoder_level );
    }
    TIM_ClearITPendingBit( TIM_ENCODER, TIM_IT_Update | TIM_IT_CC1 | TIM_IT_CC2  | TIM_IT_CC3  | TIM_IT_CC4 );
    rt_interrupt_leave();
    FREE_INT_SP();
}

//使用定时器计数方式
void encoder_init(void)
{
    GPIO_InitTypeDef        GPIO_InitStructure = {0};
    TIM_ICInitTypeDef       TIM_ICInitStructure = {0};
    TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure = {0};
    NVIC_InitTypeDef        NVIC_InitStructure = {0};

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5, ENABLE);

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    TIM_TimeBaseInitStructure.TIM_Period = 0xFFFF;
    TIM_TimeBaseInitStructure.TIM_Prescaler = 0;
    TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
    TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0x00;
    TIM_TimeBaseInit(TIM_ENCODER, &TIM_TimeBaseInitStructure);

    //使用编码器模式3
    TIM_EncoderInterfaceConfig(TIM_ENCODER, TIM_EncoderMode_TI12, TIM_ICPolarity_Falling, TIM_ICPolarity_Falling);

    TIM_ICInitStructure.TIM_Channel = TIM_Channel_1 | TIM_Channel_2;
    TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
    TIM_ICInitStructure.TIM_ICFilter = 0x0F;
    TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Falling;
    TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
    TIM_ICInit(TIM_ENCODER, &TIM_ICInitStructure);
    //TIM_PWMIConfig(TIM_ENCODER, &TIM_ICInitStructure);

    NVIC_InitStructure.NVIC_IRQChannel = TIM5_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);

    TIM_ClearITPendingBit( TIM_ENCODER, TIM_IT_Update | TIM_IT_CC1 | TIM_IT_CC2  | TIM_IT_CC3  | TIM_IT_CC4 );

    TIM_ITConfig(TIM_ENCODER, TIM_IT_Update, ENABLE);
    //TIM_ITConfig(TIM_ENCODER, TIM_IT_CC2, ENABLE);

    // //TIM_ITRxExternalClockConfig(TIM_ENCODER, TIM_TS_ITR0);
    // TIM_SelectMasterSlaveMode(TIM_ENCODER, TIM_MasterSlaveMode_Enable);
    // TIM_SelectSlaveMode(TIM_ENCODER, TIM_SlaveMode_External1);
    // TIM_SelectInputTrigger(TIM_ENCODER, TIM_TS_TI2FP2);
    // TIM_Cmd(TIM_ENCODER, ENABLE);

//    TIM_SelectInputTrigger(TIM_ENCODER, TIM_TS_TI2FP2);
//    TIM_SelectSlaveMode(TIM_ENCODER, TIM_SlaveMode_External1);
//    TIM_SelectMasterSlaveMode(TIM_ENCODER, TIM_MasterSlaveMode_Enable);


    TIM_Cmd(TIM_ENCODER, ENABLE);

    //TIM_CounterModeConfig(TIM_ENCODER, TIM_CounterMode_Up);

    encoder_pos_set(0);
}




//#define COUNTER_ZERO  1000
//
//__IO uint16_t    encoder_val = COUNTER_ZERO;
//__IO int         encoder_level = 0;
//
//int motor_encoder_pos_get(void)
//{
//    int pos = 0;
//    pos = (int)((encoder_level) * (int)65535) + encoder_val - COUNTER_ZERO;
//    return pos;
//}
//
//void motor_encoder_pos_set(int pos)
//{
//    encoder_val = COUNTER_ZERO + (pos%65535);
//    encoder_level = pos/65535;
//}
//
//void motor_encoder_isr(void)
//{
//    int dir = motor_mc_dir();
//    //计算标志位使能且上升，位置减
//    if(dir == MOTOR_DIR_DOWN)
//    {
//        if(encoder_val == 0x0000) //溢出
//        {
//          encoder_level--;
//        }
//        encoder_val--;
//    }else
//    if(dir == MOTOR_DIR_UP)
//    {
//        if(encoder_val == 0xFFFF) //溢出
//        {
//          encoder_level++;
//        }
//        encoder_val++;
//    }
//}
//
////使用中中断计数方式
//void motor_encoder_init(void)
//{
//    GPIO_InitTypeDef  GPIO_InitStructure;
//    EXTI_InitTypeDef EXTI_InitStructure;
//    NVIC_InitTypeDef NVIC_InitStructure;
//    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
//    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
//    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);
//    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD,ENABLE);
//
//    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
//
//    GPIO_InitStructure.GPIO_Pin = IN_FG_PIN;
//    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
//    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
//    GPIO_Init(IN_FG_GPIO, &GPIO_InitStructure);
//
//    GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource7);
//    EXTI_InitStructure.EXTI_Line=EXTI_Line7;
//    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
//    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
//    EXTI_InitStructure.EXTI_LineCmd = ENABLE;
//    EXTI_Init(&EXTI_InitStructure);
//
//    NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn;
//    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
//    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
//    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
//    NVIC_Init(&NVIC_InitStructure);
//
//    NVIC_SetPriority(EXTI9_5_IRQn,5<<4);
//    NVIC_EnableIRQ( EXTI9_5_IRQn );
//}
//
//
//void EXTI9_5_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
//void EXTI9_5_IRQHandler(void)
//{
//  //GET_INT_SP();
//    if( (EXTI_GetITStatus(EXTI_Line7)!=RESET) )
//    {
//        motor_encoder_isr();
//        EXTI_ClearITPendingBit(EXTI_Line7);
//    }
//    if( (EXTI_GetITStatus(EXTI_Line5)!=RESET)|| \
//        (EXTI_GetITStatus(EXTI_Line6)!=RESET)|| \
//        (EXTI_GetITStatus(EXTI_Line8)!=RESET)|| \
//        (EXTI_GetITStatus(EXTI_Line9)!=RESET) )
//    {
//        EXTI_ClearITPendingBit(EXTI_Line5|EXTI_Line6|EXTI_Line8|EXTI_Line9);
//    }
//  //FREE_INT_SP();
//}

